#include "Determinator.h"

bool Determinator::Find(int i,double* P, int count, int H, int W, int iPrev)
{
	if (count == 10&&P[i])
	{
		return true;
	}else if (count == 10&&!P[i])
	{
		return false;
	}else if (((i-W)<0)||(i%W==W-1)||(i+W>W*H-1)||(i%W ==0))
	{
		if (P[i])
			return true;
		else return false;
	}else
	{	
		bool is = false;
		int iNext = i+1;
		if ((iNext!=iPrev))
		{
			is = is||!Find(iNext,P,count+1,H,W,i);
		}
		iNext = i-1;
		if ((iNext!=iPrev))
		{
			is = is||!Find(iNext,P,count+1,H,W,i);
		}
		iNext = i + W;
		if ((iNext!=iPrev))
		{
			is = is||!Find(iNext,P,count+1,H,W,i);
		}
		iNext = i + W + 1;
		if ((iNext!=iPrev))
		{
			is = is||!Find(iNext,P,count+1,H,W,i);
		}
		iNext = i - W + 1;
		if ((iNext!=iPrev))
		{
			is = is||!Find(iNext,P,count+1,H,W,i);
		}
		iNext = i - W - 1;
		if ((iNext!=iPrev))
		{
			is = is||!Find(iNext,P,count+1,H,W,i);
		}
		if (!is)
		{
			P[i] = 0;
		}
		return is;
	}
}
void Determinator::Find1(IplImage* im, IplImage* mask)
{
	
}
void Determinator::FindInflection(IplImage* im, int*& x, int*& y, int& count)
{
	count = 0;
	IplImage* Copy = cvCloneImage(im);
	MyImage* myCopy = new MyImage(Copy);
	myCopy->UpdatePlanes();
	double* Pixels = myCopy->GetPlane()->GetPlaneAdress();
	int size = myCopy->GetPlane()->GetSize();
	int H = myCopy->height;
	int W = myCopy->width;
	for (int i =1; i<H - 1;++i)
	{
		for (int j = 1; j <W - 1; ++j )
		{
			if (Pixels[i*W+j])
			{
				int sum = 0;
				sum += (-1)*Pixels[(i+1)*W+j+1];


				sum += (-2)*Pixels[(i-1)*W+j+1];
	
				sum += (2)*Pixels[(i+1)*W+j-1];


				sum += (-1)*Pixels[(i-1)*W+j-1];

				if (sum != 0)
				{
					++count;
					Pixels[i*W+j] = 1;
					for (int n = -1; n <=1; ++n)
					{
						for (int m = -1; m <=1; ++m)
						{
							if (m==0&&n==0)
							{							
								
							}else 
							{
								Pixels[(i+n)*W+j+m] = 0;
							}
						}
					}

				}
			}

		}

	}
	x = new int[count];
	y = new int[count];
	int next = 0;
	//for (int i =0; i<H;++i)
	//{
	//	for (int j = 0; j <W; ++j )
	//	{
	//		if (Pixels[i*W+j])
	//		{
	//			x[next] = i;
	//			y[next] = j;
	//			++next;
	//		}
	//	}
	//}
	delete myCopy;
	cvReleaseImage(&Copy) ;

}
void Determinator::Delete(IplImage* im)
{

	MyImage* myCopy = new MyImage(im);
	myCopy->UpdatePlanes();
	double* Pixels = myCopy->GetPlane()->GetPlaneAdress();
	int size = myCopy->GetPlane()->GetSize();
	int H = myCopy->height;
	int W = myCopy->width;
	bool deleted = false;
	for (int i =1; i<H-1;++i)
	{
		for (int j = 1; j <W-1; ++j )
		{
			if (Pixels[i*W+j]&&!Pixels[i*W+j+1]&&!Pixels[i*W+j-1]&&!Pixels[(i+1)*W+j]&&!Pixels[(i-1)*W+j]&&!Pixels[(i+1)*W+j+1]&&!Pixels[(i+1)*W+j-1]&&!Pixels[(i-1)*W+j+1]&&!Pixels[(i-1)*W+j-1])
			{
				deleted = Find(i*W+j,Pixels,0,H,W,0);
			}
		}
	}
	myCopy->UpdateFromPlanes();

	delete myCopy;
}
IplImage* Determinator::Decrease(IplImage* im, int degree)
{
	CvSize size = cvSize(im->width/(degree/2), im->height/(degree/2));
	IplImage* newIm = cvCreateImage(size,im->depth,im->nChannels);


	char* Pixels = im->imageData;
	char* newPix = newIm->imageData;
	int newSize = newIm->width*newIm->height;
	int H = im->height;
	int W = im->width;
	for (int i = degree/2-1; i<H-degree/2;i+=degree/2)
	{
		for (int j =degree/2-1; j < W-degree/2; j+=degree/2)
		{
			int max = Pixels[i*W+j];
			for (int n = -degree/2+1; n<=degree/2-1; ++n)
			{
				if (Pixels[(i+n)*W+j]>max)
				{
					max = Pixels[(i+n)*W+j];
					Pixels[(i+n)*W+j] = 0;
				}
				if (Pixels[(i+n)*W+j+n]>max)
				{
					max = Pixels[(i+n)*W+j+n];
					Pixels[(i+n)*W+j+n] = 0;
				}
				if (Pixels[(i+n)*W+j-n]>max)
				{
					max = Pixels[(i-n)*W+j];
					Pixels[(i-n)*W+j] = 0;
				}
				if (Pixels[(i-n)*W+j]>max)
				{
					max = Pixels[(i-n)*W+j];
					Pixels[(i-n)*W+j] = 0;
				}
			}
			if ((i/(degree/2))*W/(degree/2)+j/(degree/2)<newSize)
			newPix[(i/(degree/2))*W/(degree/2)+j/(degree/2)] = max;
				
		}
	}


	return newIm;
}
bool Determinator::Compare(IplImage* im, IplImage* ex, int & step1, int & step2, int & He, int &Wi)
{

	CvSize  size = cvSize(ex->width,ex->height);
	int H = ex->height;
	int W = ex->width;
	int imH = im->height;
	int imW = im->width;
	IplImage* temp =cvCreateImage(size,ex->depth,1);
	char* Pix = im->imageData;
	char* tempPix = temp->imageData;
	char* exPix = ex->imageData;
	int stepH = 0;
	int stepW = 0;
	while (stepH <= imH - H)
	{
		while (stepW <=imW -W)
		{		
			for (int i = 0; i<H; ++i)
			{
				for (int j = 0; j<W; ++j)
				{
					tempPix[i*W+j] = Pix[(stepH +i)* imW + j+stepW];
				}
			}

			int sum = 0;
			int sumBlack = 0;
			int sumW = 0;
			int sumWight = 0;
			for (int i = 0; i<H; ++i)
			{
				for (int j = 0; j<W; ++j)
				{
					if (!tempPix[i*W+j]&&!exPix[i*W+j])
					{
						++sum;
					}
					if (!exPix[i*W+j])
					{
						++sumBlack;
					}
					if (tempPix[i*W+j]&&exPix[i*W+j])
					{
						++sumW;
					}
					if (exPix[i*W+j])
					{
						++sumWight;
					}
				}
			}
			double persent = sum/(double)sumBlack;
			double persentW = sumW/(double)sumWight;
			if (persent>0.8&&persentW>0.2)
			{
				step1 = stepH-1;
				step2 = stepW-1;
				He = H;
				Wi = W;
				return true;
			}

			stepW +=2;

		}

		stepH+=2;
	}

	return false;
}